package com.agu.api.auth.controller;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.agu.common.annotation.SysLog;
import com.agu.entity.sys.SysMenuEntity;
import com.agu.mgt.sys.controller.AbstractController;
import com.agu.mgt.sys.service.SysMenuService;
import com.agu.mgt.sys.service.SysUserService;
import com.agu.result.Result;
import com.agu.result.ResultGenerator;
import com.agu.utils.ShiroUtils;
import com.agu.utils.validator.Assert;
import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

/**
 * 认证接口
 *
 */
@RestController
@RequestMapping("/api/auth")
@Api("认证接口")
public class AuthController extends AbstractController {
	@Autowired
	private Producer producer;

	@Autowired
	private SysUserService sysUserService;
	
	@Autowired
	private SysMenuService sysMenuService;

	@ApiOperation(value = "验证码", notes = "说明")
	@RequestMapping(value = "captcha.jpg", method = RequestMethod.GET)
	public void captcha(HttpServletResponse response) throws ServletException, IOException {
		response.setHeader("Cache-Control", "no-store, no-cache");
		response.setContentType("image/jpeg");

		// 生成文字验证码
		String text = producer.createText();
		//text = "000000";
		// 生成图片验证码
		BufferedImage image = producer.createImage(text);
		// 保存到shiro session
		ShiroUtils.setSessionAttribute(Constants.KAPTCHA_SESSION_KEY, text);

		ServletOutputStream out = response.getOutputStream();
		ImageIO.write(image, "jpg", out);
		out.flush();
	}

	/**
	 * 登录
	 */
	@SysLog("登录系统")
	@ApiOperation(value = "登录", notes = "说明")
	@ApiImplicitParams({
			@ApiImplicitParam(paramType = "query", dataType = "string", name = "userName", value = "用户名", required = true),
			@ApiImplicitParam(paramType = "query", dataType = "string", name = "password", value = "密码", required = true),
			@ApiImplicitParam(paramType = "query", dataType = "string", name = "captcha", value = "验证码", required = true) })
	@RequestMapping(value = "/login", method = RequestMethod.POST)
	@ResponseBody
	public Result login(String userName, String password, String captcha) throws IOException {

		String kaptcha = ShiroUtils.getKaptcha(Constants.KAPTCHA_SESSION_KEY);
		if (captcha.equalsIgnoreCase(kaptcha)) {
			return ResultGenerator.fail("验证码不正确");
		}

		try {
			Subject subject = ShiroUtils.getSubject();
			// sha256加密
			password = new Sha256Hash(password).toHex();
			UsernamePasswordToken token = new UsernamePasswordToken(userName, password);
			subject.login(token);
		} catch (UnknownAccountException e) {
			return ResultGenerator.fail(e.getMessage());
		} catch (IncorrectCredentialsException e) {
			return ResultGenerator.fail(e.getMessage());
		} catch (LockedAccountException e) {
			return ResultGenerator.fail(e.getMessage());
		} catch (AuthenticationException e) {
			return ResultGenerator.fail("账户验证失败");
		}

		return ResultGenerator.success("登录成功");
	}

	/**
	 * 退出
	 */
	@ApiOperation(value = "退出", notes = "说明")
	@RequestMapping(value = "logout", method = RequestMethod.GET)
	public Result logout() {
		ShiroUtils.logout();
		return ResultGenerator.success("退出成功");
	}
	/**
	 * 修改登录用户密码
	 */
	@SysLog("修改密码")
	@RequestMapping("/password")
	public Result password(String password, String newPassword){
		
		Assert.isBlank(password, "原密码不为能空");
		Assert.isBlank(newPassword, "新密码不为能空");
		
		//sha256加密
		password = new Sha256Hash(password).toHex();
		//sha256加密
		newPassword = new Sha256Hash(newPassword).toHex();
				
		//更新密码
		int count = sysUserService.updatePassword(getUserId(), password, newPassword);
		if(count == 0){
			return ResultGenerator.fail("原密码不正确");
		}
		
		//退出
		//ShiroUtils.logout();
		
		return ResultGenerator.success("修改成功");
	}
	
	/**
	 * 获取登录的用户信息
	 */
	@ApiOperation(value = "登录的用户信息", notes = "说明")
	@RequestMapping(value = "/info", method = RequestMethod.GET)
	@RequiresAuthentication
	public Result info() {
		return ResultGenerator.successData(getUser());
	}

	/**
	 * 用户菜单及权限列表
	 */
	@ApiOperation(value = "菜单及权限", notes = "说明")
	@RequestMapping(value = "/menu", method = RequestMethod.GET)
	@RequiresAuthentication
	public Result menu() {
		List<SysMenuEntity> menuList = sysMenuService.getUserMenuList(getUserId());
		Set<String> permissions = sysMenuService.getUserPermissions(getUserId());

		Map map = new HashMap();
		map.put("menuList", menuList);
		map.put("permissions", permissions);

		return ResultGenerator.successData(map);
	}

}
